import numpy

from utils.numer_utils import math


class ByteReader:
    def __init__(self, data, pos):
        # data 字节数组
        self.data = data
        # pos 读取字节数组的位置
        self.pos: numpy.uint32 = pos

    def setData(self, data):
        self.data = data
        self.pos = 0
        return self

    def getPos(self) -> numpy.uint32:
        return self.pos

    def readUInt8(self) -> numpy.uint8:
        val = self.data[self.pos]
        self.pos += 1
        return val

    def readBytes(self, n):
        bytes = self.data[self.pos:self.pos + n]
        self.pos += n
        return bytes

    def readUInt16(self) -> numpy.uint16:
        bytes_read = self.readBytes(n=2)
        return math.bigEndianUint16(bytes_read)

    def readUInt32(self) -> numpy.uint32:
        bytes_read = self.readBytes(n=4)
        return math.bigEndianUInt32(bytes_read)

    def readUInt64(self) -> numpy.uint64:
        bytes_read = self.readBytes(n=8)
        return math.bigEndianUInt64(bytes_read)


class ClassReader(ByteReader):
    def __init__(self, data, pos):
        super().__init__(data=data, pos=pos)


class ConstantData(ByteReader):
    def __init__(self, data, pos, capacity):
        super().__init__(data=data, pos=pos)
        self.capacity = capacity


class AttributeData(ByteReader):
    def __init__(self, data, pos):
        super().__init__(data=data, pos=pos)


class MethodCodeReader(ByteReader):
    def __init__(self, data, pos):
        super().__init__(data=data, pos=pos)

    def reset(self, data, pos):
        self.data = data
        self.pos = pos

    def skipPadding(self):
        while self.pos % 4 != 0:
            self.readUInt8()
